using AutoMapper;
using B.S.NewMedical.Api.Read.Application.Command.ContentManagement.Hospital;
using B.S.NewMedical.Api.Read.DTOS.Hospital;
using B.S.NewMedical.Api.Read.DTOS.Department;
using B.S.NewMedical.Domain.Hospital;
using B.S.NewMedical.Domain.Doctor;
using B.S.NewMedical.ErrorCode;
using B.S.NewMedical.Infrastructure.Interface;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.NewMedical.Api.Read.Application.Handler.ContentManagement.Hospital
{
    /// <summary>
    /// 医院搜索处理器
    /// </summary>
    public class SearchHospitalHandler : IRequestHandler<SearchHospitalCommand, ApiPageing<HospitalDto>>
    {
        private readonly IBaseRepository<HospitalModel> _hospitalRepository;
        private readonly IBaseRepository<HospitalDepartmentModel> _hospitalDepartmentRepository;
        private readonly IBaseRepository<DepartmentModel> _departmentRepository;
        private readonly ILogger<SearchHospitalHandler> _logger;
        private readonly IMapper _mapper;

        public SearchHospitalHandler(
            IBaseRepository<HospitalModel> hospitalRepository,
            IBaseRepository<HospitalDepartmentModel> hospitalDepartmentRepository,
            IBaseRepository<DepartmentModel> departmentRepository,
            ILogger<SearchHospitalHandler> logger,
            IMapper mapper)
        {
            _hospitalRepository = hospitalRepository ?? throw new ArgumentNullException(nameof(hospitalRepository));
            _hospitalDepartmentRepository = hospitalDepartmentRepository ?? throw new ArgumentNullException(nameof(hospitalDepartmentRepository));
            _departmentRepository = departmentRepository ?? throw new ArgumentNullException(nameof(departmentRepository));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
            _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
        }

        /// <summary>
        /// 处理医院搜索请求
        /// </summary>
        public async Task<ApiPageing<HospitalDto>> Handle(SearchHospitalCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始搜索医院，医院名称：{HospitalName}，地区：{Region}，页码：{PageIndex}，页大小：{PageSize}",
                    request.HospitalName, request.Region, request.PageIndex, request.PageSize);

                // 构建查询
                var query = _hospitalRepository.GetAll().Where(h => !h.IsDeleted);

                // 应用搜索条件
                if (!string.IsNullOrWhiteSpace(request.HospitalName))
                {
                    query = query.Where(h => h.HospitalName != null && h.HospitalName.Contains(request.HospitalName));
                }

                if (!string.IsNullOrWhiteSpace(request.Region))
                {
                    query = query.Where(h => h.Region != null && h.Region.Contains(request.Region));
                }

                // 按推荐状态排序，推荐的排在前面，然后按ID排序
                query = query.OrderByDescending(h => h.IsRecommended ?? false).ThenBy(h => h.Id);

                // 计算总记录数
                var totalCount = await query.CountAsync(cancellationToken);

                // 分页查询
                var hospitals = await query
                    .Skip((request.PageIndex - 1) * request.PageSize)
                    .Take(request.PageSize)
                    .ToListAsync(cancellationToken);

                // 获取医院ID列表
                var hospitalIds = hospitals.Select(h => h.Id).ToList();

                // 查询医院科室关联信息
                var hospitalDepartments = await _hospitalDepartmentRepository.GetAll()
                    .Where(hd => !hd.IsDeleted && hospitalIds.Contains(hd.HospitalId))
                    .ToListAsync(cancellationToken);

                // 获取科室ID列表
                var departmentIds = hospitalDepartments.Select(hd => hd.DepartmentId).Distinct().ToList();

                // 查询科室信息
                var departments = await _departmentRepository.GetAll()
                    .Where(d => !d.IsDeleted && departmentIds.Contains(d.Id))
                    .ToListAsync(cancellationToken);

                // 映射医院数据
                var hospitalDtos = new List<HospitalDto>();

                foreach (var hospital in hospitals)
                {
                    var hospitalDto = _mapper.Map<HospitalDto>(hospital);

                    // 获取该医院的科室
                    var hospitalDeptIds = hospitalDepartments
                        .Where(hd => hd.HospitalId == hospital.Id)
                        .Select(hd => hd.DepartmentId)
                        .ToList();

                    var hospitalDepts = departments
                        .Where(d => hospitalDeptIds.Contains(d.Id))
                        .ToList();

                    // 映射科室信息
                    hospitalDto.DepartmentSetup = _mapper.Map<List<DepartmentDto>>(hospitalDepts);

                    hospitalDtos.Add(hospitalDto);
                }

                // 计算总页数
                var totalPages = (int)Math.Ceiling(totalCount / (double)request.PageSize);

                _logger.LogInformation("医院搜索完成，找到 {TotalCount} 个结果", totalCount);

                return new ApiPageing<HospitalDto>
                {
                    Code = ApiEnum.Success,
                    Msg = "搜索成功",
                    Data = null, // 分页数据不使用Data字段
                    TotaCount = totalCount,
                    TotaPage = totalPages,
                    PageData = hospitalDtos
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "搜索医院时发生错误，医院名称：{HospitalName}，地区：{Region}", 
                    request.HospitalName, request.Region);
                return new ApiPageing<HospitalDto>
                {
                    Code = ApiEnum.Error,
                    Msg = "搜索失败：" + ex.Message,
                    TotaCount = 0,
                    TotaPage = 0,
                    PageData = new List<HospitalDto>()
                };
            }
        }
    }
}